#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<unistd.h>
#include<dirent.h>
#include<fcntl.h>

int is_dir(char *path) //judge path is a diretory
{
	struct stat s_buf;
	stat(path,&s_buf);
	//return S_ISDIR(s_buf.st_mode);
	if(S_ISDIR(s_buf.st_mode)) return 1;
	else return 0;
}

char *FindsrcName(char *srcPath)  //Find the src file or floder Name
{
    char *copy = malloc(strlen(srcPath));
    strcpy(copy,srcPath);
    char *Path = malloc(strlen(copy)+1);
    *(Path+0) = '/';
    int i;
    for(i=1;i<strlen(copy)+1;i++)
	{
		*(Path+i)=*(copy+i-1);
	}
    // if(Path[strlen(Path)-1] == '/') Path[strlen(Path)-1] = '\0';  //delete the end '/',if it is.
    char *srcName = strrchr(Path,'/');
    return srcName;
}

int copy_file(char *srcPath,char *destPath)
{
	int fd;
	int len;
	char *data=NULL;

	//read_file
	fd = open(srcPath,O_RDONLY);
	if(fd < 0)
	{
		printf("can't find file named:%s\n",srcPath);
		return 0;
	}
	len = lseek(fd,0,SEEK_END);
	data = (char *)malloc(len+1);
	lseek(fd,0,SEEK_SET);
	read(fd,data,len);
	close(fd);
	
	//write_file
	char *dest_copy = malloc(strlen(destPath));
	strcpy(dest_copy,destPath);
    if(is_dir(destPath))
    {
        char *srcName = FindsrcName(srcPath);  //  "fileName"  or  "folderName"
        dest_copy = realloc(dest_copy,strlen(dest_copy)+strlen(srcName));
	int i;
	for(i=strlen(dest_copy);i<strlen(destPath)+strlen(srcName);i++)
	{
		*(dest_copy+i)=*(srcName+i-strlen(destPath));
	}
    }
    	printf("Copy file %s to file %s\n",srcPath,dest_copy);
	int t;
	scanf("%d",&t);
	if(t==0) return 0;
	fd = creat(dest_copy,S_IRUSR | S_IWUSR);
	//fd = open(dest_copy,O_CREAT | O_WRONLY,0777);
	lseek(fd,0,SEEK_SET);
	write(fd,data,len);
	close(fd);
	return 1;
}

int copy_folder(char *srcPath,char *destPath)
{
	char new_srcPath[4096];
	char new_destPath[4096];

	DIR *srcDp = opendir(srcPath);
	if(srcDp == NULL)
	{
		printf("1:can't open floder named:%s\n",srcPath);
		return 0;
	}

    //DIR *destDp = opendir(destPath);
	//if(destDp == NULL)
	//{
	//	printf("2:can't open floder named:%s\n",destPath);
	//	return 0;
	//}
        
    char *src_copy = malloc(strlen(srcPath));
    int j;
    for(j=0;j<strlen(srcPath);j++)
    {
	    *(src_copy+j)=*(srcPath+j);
    }
    char *dest_copy = malloc(strlen(destPath));
    for(j=0;j<strlen(destPath);j++)
    {
	    *(dest_copy+j)=*(destPath+j);
    }

	mkdir(dest_copy,0777);
	
	printf("Copy folder %s to folder %s\n",src_copy,dest_copy);
	int t;
	scanf("%d",&t);
	if(t==0) return 0;
	struct dirent *srcDirent = readdir(srcDp);
	//int flag = 0;
	while((srcDirent != NULL))
	{
		//flag++;
		if(strncmp(srcDirent->d_name,".",1) != 0)
		{
			//int len = strlen(srcDirent->d_name);
			//int len1 = strlen(src_copy) + len;
			//new_srcPath = (char * )realloc("\0",len1+1);
			//int len2 = strlen(dest_copy) + len;
			//new_destPath = (char * )realloc("\0",len2+1);

			bzero(new_srcPath,sizeof(new_srcPath));
			bzero(new_destPath,sizeof(new_destPath));

			sprintf(new_srcPath,"%s/%s",src_copy,srcDirent->d_name);
			sprintf(new_destPath,"%s/%s",dest_copy,srcDirent->d_name);

			if(srcDirent->d_type == DT_DIR)
				copy_folder(new_srcPath,new_destPath);
			else 
				copy_file(new_srcPath,new_destPath);

		}
		srcDirent = readdir(srcDp);
	}
	closedir(srcDp);
	return 0;
}

int main(int argc,char *argv[])
{
	if(argc != 3)
	{
		printf("Please use srcfile destfile\n");
		return 0;
	}

	char *srcPath = argv[1];
	char *destPath = argv[2];

    if(srcPath[strlen(srcPath)-1] == '/') srcPath[strlen(srcPath)-1] = '\0';      //delete the end '/',if it is.
    if(destPath[strlen(destPath)-1] == '/') destPath[strlen(destPath)-1] = '\0';  //delete the end '/',if it is.

    if(access(srcPath,F_OK)!=0||access(destPath,F_OK)!=0)
    {
        printf("%s\n","file Non-existent");
        return 0;
    }

    if(is_dir(srcPath)) //folder to folder
    {
	int j;
	char *srcName = FindsrcName(srcPath);
	char *dest_copy = malloc(strlen(destPath)+strlen(srcName));
	for(j=0;j<strlen(destPath);j++)
	{
		*(dest_copy+j)=*(destPath+j);
	}
	for(j=strlen(destPath);j<strlen(destPath)+strlen(srcName);j++)
	{
		*(dest_copy+j)=*(srcName+j-strlen(destPath));
	}
        copy_folder(srcPath,dest_copy);
    }
    else  //file to file or file to folder 
    {
        copy_file(srcPath,destPath);
    }
    return 0;
}
